/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package servlets;

import AsocUsu.UnidadFamiliar;
import AsocUsu.Usuario;
import baseDatos.ConsultasBD;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

import org.apache.commons.fileupload.*;
import org.apache.commons.fileupload.servlet.*;
import org.apache.commons.fileupload.disk.*;
/**
 *
 * @author oracle
 */
public class AnadirUsuXLS extends HttpServlet {
    private ConsultasBD baseDatos;
    HttpSession sesion;
    private String camposFichero [] = new String [13];
    private int correspondencias[] = new int [13];
    private String fichero;
    private int offset = 0;
    private boolean incluirPrimeraFila = false;
    /** 
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        sesion = request.getSession();

        String campos [] = {"Número de expediente", "DNI", "Nombre", "Apellidos", "Tarjeta de residente",
                            "Nacionalidad", "Fecha de nacimiento", "Tipo de vía", "Nombre de la vía", "Número de la vía",
                            "Ciudad", "Provincia", "CP"};

        
        if (request.getParameter("formulario") == null && request.getParameter("add") == null){
           System.out.println("Recibimos el fichero");
           File destino=new File("./Docs");
           destino.mkdir();

           // Convertimos el HTTPRequest en un ContextRequest,
           // este paso es necesario en la ultima version,
           // ya que los metodos de las versiones anteriores
           // se han quedado desfasados.
           ServletRequestContext src=new ServletRequestContext(request);

           //Si el formulario es enviado con Multipart
           if(ServletFileUpload.isMultipartContent(src)){

                try {
                    //Necesario para evitar errores de NullPointerException
                    //    DiskFileItemFactory factory = new DiskFileItemFactory((1024*1024*5),destino);
                    DiskFileItemFactory factory = new DiskFileItemFactory();
                    //Creamos un FileUpload
                    ServletFileUpload upload = new ServletFileUpload(factory);
                    // limito a 5 Mb el humbral del tamaño del archivo a subir
                    upload.setSizeMax(new Long(1024 * 1024 * 5)); // 1024 x 300 = 307200 bytes = 300 Kb
                    //Procesamos el request para que nos devuelva una lista
                    //con los parametros y ficheros.
                    List lista = upload.parseRequest(src);
                    File file = null;
                    //Recorremos la lista.
                    Iterator it = lista.iterator();
                    while (it.hasNext()) {
                        //Rescatamos el fileItem
                        FileItem item = (FileItem) it.next();
                        if (item.getSize() < 5242880) {
                            // menor de 5MB
                            //Si no, es un fichero y lo subimos al servidor.
                            //Primero creamos un objeto file a partir del nombre del fichero.
                            file = new File(item.getName());
                            //Lo escribimos en el disco
                            // usando la ruta donde se guardara el fichero
                            // y cogiendo el nombre del file
                            // Nota: Se podria hacer usando el objeto item en vez del file directamente
                            // Pero esto puede causar incompatibilidades segun que navegador, ya que
                            // algunos solo pasan el nombre del fichero subido, pero otros
                            // como Iexplorer, pasan la ruta absoluta, y esto crea un pequeño problema al escribir
                            // el fichero en el servidor.
                            File ficheroDestino = new File(destino, file.getName());
                            item.write(ficheroDestino);
                            fichero = "./Docs/" + file.getName();
                            this.leerContenidoPrimeraFila(fichero);
                            sesion.setAttribute("enviado", "true");
                            response.sendRedirect("../enviarXLS.jsp");
                        } else {
                            response.sendRedirect("../error.jsp");
                        }
                    }
                } catch (Exception ex) {
                    response.sendRedirect("../error.jsp");
                    Logger.getLogger(AnadirUsuXLS.class.getName()).log(Level.SEVERE, null, ex);                
                }
           }
        }else if (request.getParameter("formulario") != null){
            System.out.println("Ponemos los atributos");
            //Ponemos las variables de sesion
            sesion.setAttribute(campos[Integer.parseInt((String) request.getParameter("0b"))], camposFichero[Integer.parseInt((String) request.getParameter("0f"))]);
            sesion.setAttribute(campos[Integer.parseInt((String) request.getParameter("1b"))], camposFichero[Integer.parseInt((String) request.getParameter("1f"))]);
            sesion.setAttribute(campos[Integer.parseInt((String) request.getParameter("2b"))], camposFichero[Integer.parseInt((String) request.getParameter("2f"))]);
            sesion.setAttribute(campos[Integer.parseInt((String) request.getParameter("3b"))], camposFichero[Integer.parseInt((String) request.getParameter("3f"))]);
            sesion.setAttribute(campos[Integer.parseInt((String) request.getParameter("4b"))], camposFichero[Integer.parseInt((String) request.getParameter("4f"))]);
            sesion.setAttribute(campos[Integer.parseInt((String) request.getParameter("5b"))], camposFichero[Integer.parseInt((String) request.getParameter("5f"))]);
            sesion.setAttribute(campos[Integer.parseInt((String) request.getParameter("6b"))], camposFichero[Integer.parseInt((String) request.getParameter("6f"))]);
            sesion.setAttribute(campos[Integer.parseInt((String) request.getParameter("7b"))], camposFichero[Integer.parseInt((String) request.getParameter("7f"))]);
            sesion.setAttribute(campos[Integer.parseInt((String) request.getParameter("8b"))], camposFichero[Integer.parseInt((String) request.getParameter("8f"))]);
            sesion.setAttribute(campos[Integer.parseInt((String) request.getParameter("9b"))], camposFichero[Integer.parseInt((String) request.getParameter("9f"))]);
            sesion.setAttribute(campos[Integer.parseInt((String) request.getParameter("10b"))], camposFichero[Integer.parseInt((String) request.getParameter("10f"))]);
            sesion.setAttribute(campos[Integer.parseInt((String) request.getParameter("11b"))], camposFichero[Integer.parseInt((String) request.getParameter("11f"))]);
            sesion.setAttribute(campos[Integer.parseInt((String) request.getParameter("12b"))], camposFichero[Integer.parseInt((String) request.getParameter("12f"))]);

            //Hacemos el array de correspondencias
            correspondencias[Integer.parseInt((String) request.getParameter("0b"))] = Integer.parseInt((String) request.getParameter("0f"));
            correspondencias[Integer.parseInt((String) request.getParameter("1b"))] = Integer.parseInt((String) request.getParameter("1f"));
            correspondencias[Integer.parseInt((String) request.getParameter("2b"))] = Integer.parseInt((String) request.getParameter("2f"));
            correspondencias[Integer.parseInt((String) request.getParameter("3b"))] = Integer.parseInt((String) request.getParameter("3f"));
            correspondencias[Integer.parseInt((String) request.getParameter("4b"))] = Integer.parseInt((String) request.getParameter("4f"));
            correspondencias[Integer.parseInt((String) request.getParameter("5b"))] = Integer.parseInt((String) request.getParameter("5f"));
            correspondencias[Integer.parseInt((String) request.getParameter("6b"))] = Integer.parseInt((String) request.getParameter("6f"));
            correspondencias[Integer.parseInt((String) request.getParameter("7b"))] = Integer.parseInt((String) request.getParameter("7f"));
            correspondencias[Integer.parseInt((String) request.getParameter("8b"))] = Integer.parseInt((String) request.getParameter("8f"));
            correspondencias[Integer.parseInt((String) request.getParameter("9b"))] = Integer.parseInt((String) request.getParameter("9f"));
            correspondencias[Integer.parseInt((String) request.getParameter("10b"))] = Integer.parseInt((String) request.getParameter("10f"));
            correspondencias[Integer.parseInt((String) request.getParameter("11b"))] = Integer.parseInt((String) request.getParameter("11f"));
            correspondencias[Integer.parseInt((String) request.getParameter("12b"))] = Integer.parseInt((String) request.getParameter("12f"));

            //Hacemos la redireccion
            response.sendRedirect("../confEnvio.jsp");
        }else if (request.getParameter("add") != null){
            System.out.println("Insertamos en la base de datos");

            //Eliminamos todos los atributos de la sesion
            sesion.removeAttribute("enviado");
            Enumeration atributos = sesion.getAttributeNames();
            String nombreAtt;
            while(atributos.hasMoreElements()){
                nombreAtt = (String)atributos.nextElement();
                if (!nombreAtt.equalsIgnoreCase("usuario") && !nombreAtt.equalsIgnoreCase("cif")){
                    sesion.removeAttribute(nombreAtt);
                }
            }
            
            try {
                String error = this.leerContenidoFicheroUsuario(fichero, incluirPrimeraFila);
                if (error !=null && error.length() > 0){
                    sesion.setAttribute("error", error);
                    response.sendRedirect("../error.jsp");
                } else
                    response.sendRedirect("../ok.jsp");
            } catch (SQLException ex) { //Falla algo en la base de datos
                response.sendRedirect("../error.jsp");
                Logger.getLogger(AnadirUsuXLS.class.getName()).log(Level.SEVERE, null, ex);
            } catch (Exception ex) { //Falla algo en la optención de cada campo
                response.sendRedirect("../error.jsp");
                Logger.getLogger(AnadirUsuXLS.class.getName()).log(Level.SEVERE, null, ex);
            }    
        }
    }

    private String [] leerContenidoPrimeraFila(String fichero) throws IOException, Exception{
        Workbook wb = new HSSFWorkbook(new FileInputStream(fichero));

        Sheet sheet1 = wb.getSheetAt(0);

        int indice = 0;
        for (Row row : sheet1){
            System.out.println("LA primera fila con datos es: " + row.getRowNum());
            System.out.println("La primera celda con datos es: " + row.getFirstCellNum());
            offset = row.getFirstCellNum();
            for (Cell cell : row){
                if (cell != null){
                    System.out.println(cell.getColumnIndex() + " - " + this.getContent(cell));
                    if (cell.getColumnIndex() == offset + 9 && cell.getCellType() == 0){
                        incluirPrimeraFila = true;
                    }
                    sesion.setAttribute(String.valueOf(indice), this.getContent(cell));
                    camposFichero[indice] = this.getContent(cell);
                    indice++;
                }
            }
            break;
        }
        return camposFichero;
    }

    private String leerContenidoFicheroUsuario(String fichero, boolean primeraFila) throws SQLException, Exception {
        try {
            Workbook wb = new HSSFWorkbook(new FileInputStream(fichero));
            //Insertamos los usuarios
            Sheet sheet1 = wb.getSheetAt(0);
            baseDatos = new ConsultasBD();
            String nExp;
            String dni;
            String nombre;
            String apellidos;
            String tarjResi;
            String nacionalidad;
            String fechaNac;
            String tipoVia;
            String nombreVia;
            int numVia;
            String ciudad;
            String provincia;
            int cp;
            String insercionesErroneas = "";
            Usuario u = null;
            for (Row row : sheet1) {
                if (!(!primeraFila && row.getRowNum() == sheet1.getFirstRowNum())){
                    nExp = this.getContent(row.getCell(correspondencias[0] + offset));
                    dni = this.getContent(row.getCell(correspondencias[1] + offset));
                    nombre = this.getContent(row.getCell(correspondencias[2] + offset));
                    apellidos = this.getContent(row.getCell(correspondencias[3] + offset));
                    tarjResi = this.getContent(row.getCell(correspondencias[4] + offset));
                    nacionalidad = this.getContent(row.getCell(correspondencias[5] + offset));
                    fechaNac = this.getContent(row.getCell(correspondencias[6] + offset));
                    tipoVia = this.getContent(row.getCell(correspondencias[7] + offset));
                    nombreVia = this.getContent(row.getCell(correspondencias[8] + offset));
                    numVia = Integer.parseInt(this.getContent(row.getCell(correspondencias[9] + offset)));
                    ciudad = this.getContent(row.getCell(correspondencias[10] + offset));
                    provincia = this.getContent(row.getCell(correspondencias[11] + offset));
                    cp = Integer.parseInt(this.getContent(row.getCell(correspondencias[12] + offset)));
                    Usuario u2 = baseDatos.consultarUsuario(dni.toUpperCase());
                    if (u2 == null){
                        u = new Usuario(nExp.toUpperCase(), dni.toUpperCase(), nombre, apellidos, tarjResi, nacionalidad, fechaNac, tipoVia, nombreVia, numVia, ciudad, provincia, cp, ((String) sesion.getAttribute("cif")).toUpperCase());
                        baseDatos.anadirUsuario(u);
                    }else {
                        insercionesErroneas += "El usuario " + u2.nombre() + " con DNI: " + u2.dni() + " ya se encuentra" +
                                "en el sistema<BR>";
                    }
                }
            }
            return insercionesErroneas;
        } catch (IOException ex) {
            Logger.getLogger(AnadirUsuXLS.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }
    }

    private void leerContenidoFicheroUnidadFamiliar(String fichero) throws IOException, FileNotFoundException{
        Workbook wb = new HSSFWorkbook(new FileInputStream(fichero));

        //Insertamos los usuarios Cabeza de familia
        Sheet sheet1 = wb.getSheetAt(1);
        String dni;
        String nExp;
        String nombre;
        String apellidos;
        String identificativo;
        String parentesco;

        baseDatos = new ConsultasBD();

        for (Row row : sheet1){
            if (row.getRowNum() != 0){
                try {
                    nExp = this.getContent(row.getCell(0));
                    identificativo = this.getContent(row.getCell(1));
                    parentesco = this.getContent(row.getCell(2));
                    nombre = this.getContent(row.getCell(3));
                    apellidos = this.getContent(row.getCell(4));
                    dni = this.getContent(row.getCell(5));
                    System.out.println(nExp + identificativo + parentesco + nombre + apellidos + dni);
                    UnidadFamiliar uf = new UnidadFamiliar(nExp.toUpperCase(), identificativo, parentesco, nombre, apellidos, dni.toUpperCase());
                    try {
                        baseDatos.anadirUnidadFamiliar(uf);
                    } catch (SQLException ex) {
                        System.out.println("Error: AnadirUsuXLS - " + ex);
                        Logger.getLogger(AnadirUsuXLS.class.getName()).log(Level.SEVERE, null, ex);
                    }
                } catch (Exception ex) {
                    Logger.getLogger(AnadirUsuXLS.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
    }

    private String getContent(Cell cell) throws Exception{
        switch(cell.getCellType()) {
            case Cell.CELL_TYPE_STRING:
                return cell.getRichStringCellValue().getString();
            case Cell.CELL_TYPE_NUMERIC:
                if(DateUtil.isCellDateFormatted(cell)) {
                  return cell.getDateCellValue().toString();
                } else {
                  Double num = cell.getNumericCellValue();
                  return String.valueOf(num.intValue());
                }
            case Cell.CELL_TYPE_BOOLEAN:
                return String.valueOf(cell.getBooleanCellValue());
            case Cell.CELL_TYPE_FORMULA:
                return cell.getCellFormula();
            default:
                return "";
		}
	}


    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /** 
     * Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
    } 

    /** 
     * Handles the HTTP <code>POST</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
    }

    /** 
     * Returns a short description of the servlet.
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>

}
